/*
若有错误代码C4996 'inet_addr': Use inet_pton() or InetPton() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings
在UDP服务器.cpp右键属性-C/C++-预处理器-预处理器定义中添加 _WINSOCK_DEPRECATED_NO_WARNINGS
*/
#include "pch.h"	//如果此头文件报错，将这个头文件删除即可
#include <iostream>
#include <iomanip>
#include <WinSock2.h>
#include<WS2tcpip.h>
#include<string>
#pragma comment(lib,"ws2_32.lib")
using namespace std;

int main()
{


	float temp;
	int n;
	int i, j;
	char ctemp[6];
	char cctemp[10][6];
	bool init_flag = 0;
	int sensor_multiple = 0;
	char c1[10] = "initiated";
	char c2[14] = "not initiated";
	char c3[14] = "request error";

	//设置版本号
	WORD sockVersion = MAKEWORD(2, 2);
	//定义一个WSADATA类型的结构体，存储被WSAStartup函数调用后返回的Windows Sockets数据
	WSADATA wsadata;
	//初始化套接字，启动构建，将“ws2_32.lib”加载到内存中
	if (WSAStartup(sockVersion, &wsadata)) {
		printf("WSAStartup failed \n");
		return 0;
	}
	//创建一个套接字，即创建一个内核对象
	SOCKET hServer = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (hServer == INVALID_SOCKET) {
		printf("socket failed \n");
		return 0;
	}
	//创建服务器端地址并绑定端口号的IP地址
	sockaddr_in addrServer;
	addrServer.sin_family = AF_INET;
	addrServer.sin_port = htons(8889);
	addrServer.sin_addr.S_un.S_addr = INADDR_ANY;

	// 初始化内核对象，传参给内核对象，此时数据可能都处于未就绪链表
	int nRet = bind(hServer, (sockaddr*)&addrServer, sizeof(addrServer));
	if (nRet == SOCKET_ERROR) {
		printf("socket bind failed\n");
		closesocket(hServer);
		WSACleanup();
		return 0;
	}
	//创建一个客服端地址
	sockaddr_in  addrClient;
	int nlen = sizeof(addrClient);
	//创建一个中间变量，用于存放用户输入的信息
	//string str;

	//用于接受数据的缓冲区。
	char buffer[1024];
	//初始化缓冲区
	memset(buffer, 0, sizeof(buffer));

	int irecv;
	int isend;

	//
	while (1)
	{
		bool recv = 0;/* 从workstation获取到数据时为1 */
		//
		irecv = recvfrom(hServer, buffer, sizeof(buffer), 0, (SOCKADDR*)&addrClient, &nlen);
		if (irecv > 0) {
			//判断数据是否为结束标志，若是则关闭服务器
			if (!(strcmp(buffer, "close"))) {
				//关闭服务器套接字
				cout << "Client: " << buffer << endl;
				cout << "close connection··· " << endl;
				closesocket(hServer);
				WSACleanup();
				cout << "5s后关闭控制它。" << endl;
				Sleep(5000);
				return 0;
			}
			else {
				cout << " Client：" << buffer << endl;
			}
		}
		//接受数据失败
		else {
			cout << "recvFrom failed " << endl;
			closesocket(hServer);
			WSACleanup();
			cout << "5s后关闭控制台。" << endl;
			Sleep(5000);
			return 0;
		}
		recv = 1;
		//
		if (recv)
		{
			char request[255];/* 从workstation获取 */
			strcpy_s(request, buffer);
			memset(buffer, 0, sizeof(buffer));

			if (!strcmp(request, "init"))/* request为init */
			{
				srand(time(NULL));
				init_flag = 1;
				strcpy_s(buffer, "初始化成功");
				isend = sendto(hServer, buffer, strlen(buffer), 0, (SOCKADDR*)&addrClient, nlen);/* 传给workstation初始化成功,c1 */
				memset(buffer, 0, sizeof(buffer));
			}

			else if (!strcmp(request, "read"))/* request为read */
			{
				if (!init_flag)
				{
					strcpy_s(buffer, "未初始化");
					isend = sendto(hServer, buffer, strlen(buffer), 0, (SOCKADDR*)&addrClient, nlen);/* 传给workstation未初始化,c2  */
					memset(buffer, 0, sizeof(buffer));
					continue;
				}

				/* 从workstation获取读取单个或多个数的信息,更改sensor_multiple的值 */

				else
				{
					strcpy_s(buffer, "请选择模式，0为间隔测温,1为实时监测，2为报警模式:");
					isend = sendto(hServer, buffer, strlen(buffer), 0, (SOCKADDR*)&addrClient, nlen);
					memset(buffer, 0, sizeof(buffer));
				L1:irecv = recvfrom(hServer, buffer, sizeof(buffer), 0, (SOCKADDR*)&addrClient, &nlen);
					sensor_multiple = buffer[0] - '0';
					memset(buffer, 0, sizeof(buffer));
					if (sensor_multiple == 1 || sensor_multiple == 2)
					{
						temp = rand() % 501 * 0.02 + 35;
						ctemp[0] = temp / 10 + '0';
						ctemp[1] = int(temp) % 10 + '0';
						ctemp[2] = '.';
						ctemp[3] = int(temp * 100) / 10 - int(temp * 100) / 100 * 10 + '0';
						ctemp[4] = int(temp * 100) % 10 + '0';
						ctemp[5] = '\0';

						strcpy_s(buffer, ctemp);
						isend = sendto(hServer, buffer, strlen(buffer), 0, (SOCKADDR*)&addrClient, nlen);/* 传给workstation单个温度，ctemp */
						memset(buffer, 0, sizeof(buffer));
					}
					else if (!sensor_multiple)
					{
						strcpy_s(buffer, "间隔测温模式，请输入24h内测温次数n（整数）：");
						isend = sendto(hServer, buffer, strlen(buffer), 0, (SOCKADDR*)&addrClient, nlen);
						memset(buffer, 0, sizeof(buffer));

						irecv = recvfrom(hServer, buffer, sizeof(buffer), 0, (SOCKADDR*)&addrClient, &nlen);
						n = buffer[0] - '0';
						memset(buffer, 0, sizeof(buffer));

						srand(time(NULL));
						for (int i = 0; i < n; i++)
						{
							temp = rand() % 501 * 0.02 + 35;
							ctemp[0] = temp / 10 + '0';
							ctemp[1] = int(temp) % 10 + '0';
							ctemp[2] = '.';
							ctemp[3] = int(temp * 100) / 10 - int(temp * 100) / 100 * 10 + '0';
							ctemp[4] = int(temp * 100) % 10 + '0';
							ctemp[5] = '\0';

							strcpy_s(buffer, ctemp);
							isend = sendto(hServer, buffer, strlen(buffer), 0, (SOCKADDR*)&addrClient, nlen);
							memset(buffer, 0, sizeof(buffer));
							irecv = recvfrom(hServer, buffer, sizeof(buffer), 0, (SOCKADDR*)&addrClient, &nlen);

							memset(buffer, 0, sizeof(buffer));
						}
					}
					else
					{
						strcpy_s(buffer, "模式选择出错，请选择模式，0为间隔测温,1为实时监测，2为报警模式:");
						isend = sendto(hServer, buffer, strlen(buffer), 0, (SOCKADDR*)&addrClient, nlen);/* 传给workstation错误，c3 */
						memset(buffer, 0, sizeof(buffer));
						goto L1;
					}


				}

			}

			else
			{
				strcpy_s(buffer, "request error");
				isend = sendto(hServer, buffer, strlen(buffer), 0, (SOCKADDR*)&addrClient, nlen);/* 传给workstation错误，c3 */
				memset(buffer, 0, sizeof(buffer));
			}
		}
	}
	system("pause");
	return 0;
}

